package com.ruoyi.common.utils;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 功能：根据 Excel 中 B 列内容，重命名文件夹内的图片（编号 1~100，格式不限）
 * 逻辑：
 * 1. 读取 Excel 的 B 列，建立「图片编号（1~100）→ 新名称」的映射
 * 2. 遍历图片文件夹，匹配“数字.扩展名”格式的文件
 * 3. 根据编号查映射，重命名文件（保留原扩展名）
 */
public class ImageRenameByExcel {
    // 日志对象（SLF4J）
    private static final Logger log = LoggerFactory.getLogger(ImageRenameByExcel.class);

    public static void main(String[] args) {
        // ===================== 1. 配置路径（需替换为实际路径） =====================
        String excelPath = "C:\\Users\\lenovo\\Desktop\\采集列表-100张.xlsx"; // Excel 文件路径（.xlsx 格式）
        String imageDir = "C:\\Users\\lenovo\\Desktop\\mihashka.the.model (White60+)-20250613T200430Z-1-001 (2)\\mihashka.the.model (White60+)-20250613T200430Z-1-001\\mihashka.the.model (White60+)\\合格";       // 图片所在文件夹路径

        try {
            // ===================== 2. 读取 Excel，生成“编号→新名称”映射 =====================
            Map<Integer, String> nameMap = readExcelBColumn(excelPath);
            log.info("Excel 读取完成，共获取 {} 条有效映射", nameMap.size());

            // ===================== 3. 遍历图片文件夹，执行重命名 =====================
            renameImages(imageDir, nameMap);
        } catch (IOException e) {
            log.error("程序执行过程中发生 IO 异常：", e);
        }
    }

    /**
     * 读取 Excel 的 B 列（第 2 列，索引为 1），生成「图片编号（1~100）→ 新名称」的映射
     * 说明：Excel 行号从 0 开始，第 2 行（rowNum=1）对应图片编号 1，第 101 行（rowNum=100）对应编号 100
     * @param excelPath Excel 文件路径（.xlsx 格式）
     * @return 编号到新名称的映射表
     * @throws IOException IO 异常（文件不存在、读取失败等）
     */
    private static Map<Integer, String> readExcelBColumn(String excelPath) throws IOException {
        Map<Integer, String> nameMap = new HashMap<>();

        try (FileInputStream fis = new FileInputStream(excelPath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(1); // 操作第一个 Sheet（可根据需求修改）

            // 遍历 Excel 行：rowNum 从 1 到 100（对应图片编号 1~100）
            for (int rowNum =0; rowNum < 100; rowNum++) {
                Row row = sheet.getRow(rowNum);
                if (row == null) { // 行不存在（空行）
                    log.warn("Excel 第 {} 行（行号，从 0 开始）为空，跳过", rowNum);
                    continue;
                }

                Cell cell = row.getCell(1); // B 列的索引是 1
                if (cell == null) { // 单元格为空
                    log.warn("Excel 第 {} 行的 B 列单元格为空，跳过", rowNum);
                    continue;
                }

                // 强制转为字符串（避免 Excel 单元格格式问题，如数字、日期等）
                cell.setCellType(CellType.STRING);
                String newName = cell.getStringCellValue().trim(); // trim 去除首尾空格

                // 行号 rowNum 直接对应图片编号（1~100）
               Integer numsort = rowNum+1;
                nameMap.put(numsort, newName);
            }
        } catch (FileNotFoundException e) {
            log.error("Excel 文件未找到：{}", excelPath, e);
            throw e; // 抛给上层处理
        }

        return nameMap;
    }

    /**
     * 遍历图片文件夹，根据映射表重命名文件
     * 规则：仅处理“数字.扩展名”格式的文件（如 1.jpg、2.png、100.gif 等）
     * @param imageDir 图片文件夹路径
     * @param nameMap  编号到新名称的映射表
     * @throws IOException IO 异常（文件夹不存在、重命名失败等）
     */
    private static void renameImages(String imageDir, Map<Integer, String> nameMap) throws IOException {
        File dir = new File(imageDir);
        // 检查文件夹合法性
        if (!dir.exists()) {
            log.error("图片文件夹 {} 不存在！", imageDir);
            return;
        }
        if (!dir.isDirectory()) {
            log.error("路径 {} 不是文件夹！", imageDir);
            return;
        }

        // 列出所有符合“数字.扩展名”的文件（支持 jpg/jpeg/png/bmp/gif，不区分大小写）
        File[] files = dir.listFiles((file, name) -> {
            Pattern pattern = Pattern.compile(
                    "^\\d+\\.(jpg|jpeg|png|bmp|gif)$",
                    Pattern.CASE_INSENSITIVE // 扩展名不区分大小写（如 JPG、Png 也匹配）
            );
            Matcher matcher = pattern.matcher(name);
            return matcher.matches();
        });

        if (files == null || files.length == 0) {
            log.warn("图片文件夹 {} 中无符合要求的文件！", imageDir);
            return;
        }

        // 遍历文件，执行重命名
        for (File file : files) {
            String fileName = file.getName();
            // 提取“数字编号”和“扩展名”
            Matcher matcher = Pattern.compile("^(\\d+)\\.(\\w+)$").matcher(fileName);

            if (matcher.find()) {
                int num;
                try {
                    num = Integer.parseInt(matcher.group(1)); // 提取数字编号
                } catch (NumberFormatException e) {
                    log.warn("文件名 {} 的数字部分无法解析为整数，跳过", fileName, e);
                    continue;
                }
                String ext = matcher.group(2); // 提取扩展名（如 jpg、png）

                // 查映射表，获取新名称
                if (nameMap.containsKey(num)) {
                    String newName = nameMap.get(num) + "." + ext; // 新名称+原扩展名
                    File newFile = new File(dir, newName);

                    // 检查新文件是否已存在（避免覆盖）
                    if (newFile.exists()) {
                        log.warn("新文件 {} 已存在，跳过重命名原文件 {}", newName, fileName);
                        continue;
                    }

                    // 执行重命名
                    boolean renamed = file.renameTo(newFile);
                    if (renamed) {
                        log.info("重命名成功：原文件 {} → 新文件 {}", fileName, newName);
                    } else {
                        log.error("重命名失败：原文件 {} → 新文件 {}", fileName, newName);
                    }
                } else {
                    log.warn("图片 {} 的编号 {} 不在 Excel 映射表中，跳过", fileName, num);
                }
            } else {
                log.warn("文件名 {} 不符合「数字.扩展名」格式，跳过", fileName);
            }
        }
    }
}
